格雷码是一种相邻两个码字之间只有一位不同的编码方式。也叫反射二进制码(Reflected Binary Code, RBC)。
- 与普通二进制码(Binary Code)相比,格雷码每次只改变一位,而不是可能改变多位。
- 在硬件设计中最常用的是二进制到格雷码的变换(Binary to Gray),用于地址计数器、位置编码器、异步FIFO的指针同步等场景。
assign gray[3] = binary[3];
assign gray[2] = binary[3] ^ binary[2];
assign gray[1] = binary[2] ^ binary[1];
assign gray[0] = binary[1] ^ binary[0];
为什么普通二进制会产生毛刺?
在多位同步数据(如地址指针)跨时钟域传输时:
- 普通二进制的相邻计数值可能会多位同时变化。
- 由于不同位在逻辑门中的传播延迟不同,在同一个时钟边沿采样时可能采到“半新半旧”的状态,造成逻辑判断错误或异常地址跳变(毛刺)。
异步 FIFO 的指针同步
在异步 FIFO 中,写指针 wptr 和读指针 rptr 处于不同的时钟域。
- 使用格雷码转换后的写/读指针,在跨时钟域传输时,通过多级打拍同步。
- 接收方对其进行二次打拍、然后用格雷码转换回二进制再用于比较,计算 FIFO 的空/满状态。
- 因为格雷码只变一位,即使某位没同步完成,读取指针也不会“跳过多个位置”或误判断满/空